// ADORecordset.cpp: implementation of the CADORecordset class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ADORecordset.h"

#include "ADODatabase.h"
#include "atlconv.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CADORecordset::CADORecordset(CADODatabase* padoDB)
{
	m_pRecordset = NULL;
	m_padoDB = padoDB;
	m_bOpenFile = FALSE;
}

CADORecordset::CADORecordset()
{
	m_pRecordset = NULL;
	m_padoDB = NULL;
	m_bOpenFile = FALSE;
}

CADORecordset::~CADORecordset()
{

}

_RecordsetPtr CADORecordset::GetRecordset()
{
	return m_pRecordset;
}

BOOL CADORecordset::Query(CString sQuery)
{
	if(!sQuery.IsEmpty())
	{
		try
		{
			HRESULT hr;
			if(m_pRecordset == NULL)
			{
				hr = m_pRecordset.CreateInstance(__uuidof(Recordset));
				if(FAILED(hr))
				{
					m_pRecordset = NULL;
					return FALSE;
				}
				//m_pRecordset->CacheSize = 10;
			}
			if(m_pRecordset->State != adStateClosed)
				m_pRecordset->Close();
			if(!m_bOpenFile)
				hr = m_pRecordset->Open((_bstr_t)sQuery,_variant_t((IDispatch *)m_padoDB->GetConnection(), TRUE),adOpenKeyset,
					adLockPessimistic,adCmdText);
			else
				hr = m_pRecordset->Open((_bstr_t)sQuery,_variant_t((IDispatch *)m_padoDB->GetConnection(), TRUE),adOpenKeyset,
					adLockPessimistic,adCmdFile);
			if(FAILED(hr))
				return FALSE;
			return TRUE;
		}
		catch(_com_error& e)
		{
			//AfxMessageBox(e.Description());
			OutputDebugString(e.Description());
		}
	}
	return FALSE;
}

int CADORecordset::GetRecordCount()
{
	if(IsOpen())
		return m_pRecordset->RecordCount;
	return -1;
}

BOOL CADORecordset::IsOpen()
{
	if(m_pRecordset != NULL && m_pRecordset->State != adStateClosed)
		return TRUE;
	return FALSE;
}

BOOL CADORecordset::IsEOF()
{
	if(IsOpen())
		return m_pRecordset->GetadoEOF();
	return TRUE;
}

BOOL CADORecordset::IsBOF()
{
	if(IsOpen())
		return m_pRecordset->GetBOF();
	return FALSE;
}

HRESULT CADORecordset::Move(long lRecordNum, RECORDPOS rpMove)
{
	HRESULT hr = -1;
	if(IsOpen())
	{
		if(rpMove == RP_END)
			hr = m_pRecordset->Move(lRecordNum,(_variant_t)(long)adBookmarkLast);
		else if(rpMove == RP_CURRENT)
			hr = m_pRecordset->Move(lRecordNum,(_variant_t)(long)adBookmarkCurrent);
		else
			hr = m_pRecordset->Move(lRecordNum,(_variant_t)(long)adBookmarkFirst);
	}
	return hr;
}

HRESULT CADORecordset::MoveFirst()
{
	HRESULT hr = -1;
	if(IsOpen())
		hr = m_pRecordset->MoveFirst();
	return hr;
}

HRESULT CADORecordset::MoveLast()
{
	HRESULT hr = -1;
	if(IsOpen())
		hr = m_pRecordset->MoveLast();
	return hr;
}

HRESULT CADORecordset::MovePrev()
{
	HRESULT hr = -1;
	if(IsOpen())
		hr = m_pRecordset->MovePrevious();
	return hr;
}

HRESULT CADORecordset::MoveNext()
{
	HRESULT hr = -1;
	if(IsOpen())
		hr = m_pRecordset->MoveNext();
	return hr;
}

HRESULT CADORecordset::ReQuery()
{
	HRESULT hr = -1;
	if(IsOpen())
		hr = m_pRecordset->Requery(adCmdText);
	return hr;
}

BOOL CADORecordset::Filter(CString sFilter)
{
	if(IsOpen())
	{
		m_pRecordset->Filter = (_bstr_t)sFilter;
		return TRUE;
	}
	return FALSE;
}

BOOL CADORecordset::Sort(CString sSort)
{
	if(IsOpen())
	{
		m_pRecordset->Sort = (_bstr_t)sSort;
		return TRUE;
	}
	return FALSE;
}

_variant_t CADORecordset::FieldVARIANT(int iFieldNo)
{
	try
	{
		if(IsOpen())
			return m_pRecordset->Fields->GetItem((long)iFieldNo)->Value;
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return 0l;
}

_variant_t CADORecordset::FieldVARIANT(CString sFieldName)
{
	try
	{
		if(IsOpen())
			return m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value;
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return 0l;
}

void CADORecordset::FieldBlob(CString sFieldName,void** pBuf,long& iSize)
{
	iSize = 0;
	*pBuf = NULL;
	try
	{
		if(IsOpen())
		{
			iSize = m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->ActualSize;
			if(iSize > 0)
			{
				_variant_t	varBLOB;
				varBLOB = m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->GetChunk(iSize);
				if(varBLOB.vt == (VT_ARRAY | VT_UI1))
				{
					if(*pBuf = new char[iSize+1])
					{	
						void *pByte = NULL;
						SafeArrayAccessData(varBLOB.parray,(void **)&pByte);
						memcpy(*pBuf,pByte,iSize);
						SafeArrayUnaccessData(varBLOB.parray);
					}
				}
				else if(varBLOB.vt == VT_BSTR)
				{
					if(*pBuf = new char[iSize+1])
						memcpy(*pBuf,varBLOB.bstrVal,iSize);
				}
			}
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
}

CString CADORecordset::FieldName(CString sFieldName)
{
	try
	{
		if(IsOpen())
			return (LPCTSTR)/*(const char*)*/m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Name;
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return _T("");
}

CString CADORecordset::FieldName(int iFieldNo)
{
	try
	{
		if(IsOpen())
			return (LPCTSTR)/*(const char*)*/m_pRecordset->Fields->GetItem((long)iFieldNo)->Name;
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return _T("");
}

int CADORecordset::FieldInt(CString sFieldName)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value;
			if(var.vt == VT_NULL)
				return 0;
			return (int)long(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return -99999999;
}

long CADORecordset::FieldLong(CString sFieldName)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value;
			if(var.vt == VT_NULL)
				return 0;
			return long(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return -99999999;
}

BOOL CADORecordset::FieldBool(CString sFieldName)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value;
			if(var.vt == VT_NULL)
				return FALSE;
			return (BOOL)bool(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return FALSE;
}

float CADORecordset::FieldFloat(CString sFieldName)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value;
			if(var.vt == VT_NULL)
				return 0.0f;
			return float(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return -99999999.99f;
}

double CADORecordset::FieldDouble(CString sFieldName)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value;
			if(var.vt == VT_NULL || var.vt == VT_EMPTY)
				return 0.0f;
			return double(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return -99999999.99f;
}

CString CADORecordset::FieldString(CString sFieldName)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value;
			if(var.vt == VT_NULL)
				return _T("");
			var.ChangeType(VT_BSTR);
			return var.bstrVal;
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return _T("");
}

int CADORecordset::FieldCount()
{
//	if(IsOpen())
	if(m_pRecordset != NULL)
		return m_pRecordset->Fields->Count;
	return -1;
}

void CADORecordset::FieldBlob(int iFieldNo,void** pBuf,long& iSize)
{
	iSize = 0;
	*pBuf = NULL;
	try
	{
		if(IsOpen())
		{
			iSize = m_pRecordset->Fields->GetItem((long)iFieldNo)->ActualSize;
			if(iSize > 0)
			{
				_variant_t	varBLOB;
				varBLOB = m_pRecordset->Fields->GetItem((long)iFieldNo)->GetChunk(iSize);
				if(varBLOB.vt == (VT_ARRAY | VT_UI1))
				{
					if(*pBuf = new char[iSize+1])
					{	
						void *pByte = NULL;
						SafeArrayAccessData(varBLOB.parray,(void **)&pByte);
						memcpy(pBuf,pByte,iSize);
						SafeArrayUnaccessData(varBLOB.parray);
					}
				}
				else if(varBLOB.vt == VT_BSTR)
				{
					if(*pBuf = new char[iSize+1])
						memcpy(*pBuf,varBLOB.bstrVal,iSize);
				}
			}
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
}

int CADORecordset::FieldInt(int iFieldNo)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((long)iFieldNo)->Value;
			if(var.vt == VT_NULL)
				return 0;
			return (int)long(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return -99999999;
}

long CADORecordset::FieldLong(int iFieldNo)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((long)iFieldNo)->Value;
			if(var.vt == VT_NULL)
				return 0;
			return long(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return -99999999;
}

BOOL CADORecordset::FieldBool(int iFieldNo)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((long)iFieldNo)->Value;
			if(var.vt == VT_NULL)
				return FALSE;
			return (BOOL)bool(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return FALSE;
}

float CADORecordset::FieldFloat(int iFieldNo)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((long)iFieldNo)->Value;
			if(var.vt == VT_NULL)
				return 0.0f;
			return float(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return -99999999.99f;
}

double CADORecordset::FieldDouble(int iFieldNo)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((long)iFieldNo)->Value;
			if(var.vt == VT_NULL || var.vt ==  VT_EMPTY)
				return 0.0f;
			return double(var);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return -99999999.99f;
}

CString CADORecordset::FieldString(int iFieldNo)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((long)iFieldNo)->Value;
			if(var.vt == VT_NULL)
				return _T("");
			var.ChangeType(VT_BSTR);
			return var.bstrVal;
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return _T("");
}

COleDateTime CADORecordset::FieldODT(CString sFieldName)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((_variant_t)sFieldName)->Value;
			if(var.vt == VT_NULL)
				return COleDateTime(1800,1,1,0,0,1);
			return (COleDateTime)var.date;
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return COleDateTime(1800,1,1,0,0,1);
}

COleDateTime CADORecordset::FieldODT(int iFieldNo)
{
	try
	{
		if(IsOpen())
		{
			_variant_t var = m_pRecordset->Fields->GetItem((long)iFieldNo)->Value;
			if(var.vt == VT_NULL)
				return COleDateTime(1800,1,1,0,0,1);
			return (COleDateTime)var.date;
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return COleDateTime(1800,1,1,0,0,1);
}

BOOL CADORecordset::Seek(CString sKeyValues, int iSeekType)
{
	try
	{
		if(IsOpen())
		{
			HRESULT hr = m_pRecordset->Seek((_bstr_t)sKeyValues,adSeekFirstEQ);
			return SUCCEEDED(hr);
		}
	}
	catch(_com_error &e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return FALSE;
}
// 
// void CADORecordset::SetField(int iFieldNo,_variant_t stValue)
// {
// 
// }
void CADORecordset::SetField(CString sFieldName,void* pBuf,int iSize)
{
	VARIANT			varBLOB;
	SAFEARRAY		*psa;
    SAFEARRAYBOUND	rgsabound[1];
	if(pBuf != NULL)
	{
		rgsabound[0].lLbound = 0;
		rgsabound[0].cElements = iSize;
		psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
		BYTE* pByte;
		if(SafeArrayAccessData(psa,(void**)&pByte) == NOERROR)
			memcpy((LPVOID)pByte,(LPVOID)pBuf,iSize);
		SafeArrayUnaccessData(psa);

		varBLOB.vt = VT_ARRAY | VT_UI1;
		varBLOB.parray = psa;
		m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->AppendChunk(varBLOB);
	}
}

void CADORecordset::SetField(CString sFieldName, LPCTSTR pszValue)
{
	SetField(sFieldName, (CString)pszValue);
}

void CADORecordset::SetField(CString sFieldName, CString sValue)
{
	if(IsOpen())
	{
		int iFieldSize = m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->DefinedSize;
		if(sValue.GetLength() > iFieldSize)
			sValue = sValue.Left(iFieldSize);
		m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value = _bstr_t(sValue);
	}
}

void CADORecordset::SetField(CString sFieldName, int iValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value = (long)iValue;
}

void CADORecordset::SetField(CString sFieldName, long lValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value = (long)lValue;
}

void CADORecordset::SetField(CString sFieldName, bool bValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value = bValue;
}

void CADORecordset::SetField(CString sFieldName, COleDateTime odtValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value = (_variant_t)odtValue;
}

void CADORecordset::SetField(CString sFieldName, float fValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value = fValue;
}

void CADORecordset::SetField(CString sFieldName, double dValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value = dValue;
}

void CADORecordset::SetField(int iFieldNo,void* pBuf,int iSize)
{
	VARIANT			varBLOB;
	SAFEARRAY		*psa;
    SAFEARRAYBOUND	rgsabound[1];
	if(pBuf != NULL)
	{
		rgsabound[0].lLbound = 0;
		rgsabound[0].cElements = iSize;
		psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
		BYTE* pByte;
		if(SafeArrayAccessData(psa,(void**)&pByte) == NOERROR)
			memcpy((LPVOID)pByte,(LPVOID)pBuf,iSize);
		SafeArrayUnaccessData(psa);

		varBLOB.vt = VT_ARRAY | VT_UI1;
		varBLOB.parray = psa;
		m_pRecordset->Fields->GetItem((long)iFieldNo)->AppendChunk(varBLOB);
	}
}
void CADORecordset::SetField(int iFieldNo, LPCTSTR pszValue)
{
	SetField(iFieldNo,(CString)pszValue);
}
void CADORecordset::SetField(int iFieldNo, CString sValue)
{
	if(IsOpen())
	{
		int iFieldSize = m_pRecordset->Fields->GetItem((long)iFieldNo)->DefinedSize;
		if(sValue.GetLength() > iFieldSize)
			sValue = sValue.Left(iFieldSize);
		m_pRecordset->Fields->GetItem((long)iFieldNo)->Value = (_bstr_t)sValue;
	}
}

void CADORecordset::SetField(int iFieldNo, int iValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((long)iFieldNo)->Value = (long)iValue;
}

void CADORecordset::SetField(int iFieldNo, long lValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((long)iFieldNo)->Value = (long)lValue;
}

void CADORecordset::SetField(int iFieldNo, bool bValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((long)iFieldNo)->Value = bValue;
}

void CADORecordset::SetField(int iFieldNo, COleDateTime odtValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((long)iFieldNo)->Value = (_variant_t)odtValue;
}

void CADORecordset::SetField(int iFieldNo, float fValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((long)iFieldNo)->Value = fValue;
}

void CADORecordset::SetField(int iFieldNo, double dValue)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((long)iFieldNo)->Value = dValue;
}

void CADORecordset::SetField(int iFieldNo,_variant_t& val)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((long)iFieldNo)->Value = val;
}

void CADORecordset::SetField(CString sFieldName,_variant_t& val)
{
	if(IsOpen())
		m_pRecordset->Fields->GetItem((_bstr_t)sFieldName)->Value = val;
}

BOOL CADORecordset::Update()
{
	if(IsOpen())
	{
		HRESULT hr = m_pRecordset->Update();
		return SUCCEEDED(hr);
	}
	return FALSE;
}

void CADORecordset::CancelUpdate()
{
	if(IsOpen())
		m_pRecordset->CancelUpdate();
}

BOOL CADORecordset::BeChange()
{
	BOOL bChange = FALSE;
	for(long lFieldNo = 0;lFieldNo < m_pRecordset->Fields->Count;lFieldNo++)
	{
		_variant_t OrgValue = m_pRecordset->Fields->GetItem(lFieldNo)->OriginalValue;
		_variant_t Value = m_pRecordset->Fields->GetItem(lFieldNo)->Value;
		if(OrgValue != Value)
		{
			bChange = TRUE;
			break;
		}
	}
	return bChange;
}

BOOL CADORecordset::AddNew()
{
	if(IsOpen())
	{
		HRESULT hr = m_pRecordset->AddNew();
		return SUCCEEDED(hr);
	}
	return FALSE;
}

long CADORecordset::GetRecordNo()
{
	if(IsOpen())
		return (m_pRecordset->AbsolutePosition - 1);
	return 0;
}

void CADORecordset::Close()
{
	if(IsOpen())
		m_pRecordset->Close();
}

BOOL CADORecordset::OpenFile(CString sFileName)
{
	m_bOpenFile = TRUE;
	BOOL bRet = Query(sFileName);
	m_bOpenFile = FALSE;
	return bRet;
}

BOOL CADORecordset::SaveFile(CString sFileName)
{
	if(IsOpen())
	{
		HRESULT hr = m_pRecordset->Save((_bstr_t)sFileName,adPersistXML);
		return SUCCEEDED(hr);
	}
	return FALSE;
}

BOOL CADORecordset::Delete(AffectEnum affect)
{
	if(IsOpen())
	{
		HRESULT hr = m_pRecordset->Delete(affect);
		return SUCCEEDED(hr);
	}
	return FALSE;
}

BOOL CADORecordset::Open(CString sQuery)
{
	return Query(sQuery);
}

BOOL CADORecordset::Execute(CString sQuery)
{
	if(m_padoDB != NULL)
	{
		m_padoDB->GetConnection()->Execute((_bstr_t)sQuery,NULL,adCmdUnknown);
		return TRUE;
	}
	return FALSE;
}

BOOL CADORecordset::OpenNoConnect()
{
	try
	{
		HRESULT hr;
		if(m_pRecordset == NULL)
		{
			hr = m_pRecordset.CreateInstance(__uuidof(Recordset));
			if(FAILED(hr))
			{
				m_pRecordset = NULL;
				return FALSE;
			}
			m_pRecordset->CacheSize = 10;
			m_pRecordset->CursorLocation = adUseClient;
		}
		if(m_pRecordset->State != adStateClosed)
			m_pRecordset->Close();
		hr = m_pRecordset->Open(vtMissing,vtMissing,adOpenStatic,adLockOptimistic,adCmdTable);
		if(FAILED(hr))
			return FALSE;
		return TRUE;
	}
	catch(_com_error& e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return FALSE;
}

BOOL CADORecordset::AddField(CString strFieldName,AdoNS::DataTypeEnum DataType,int iSize,AdoNS::FieldAttributeEnum Attribute)
{
	try
	{
		HRESULT hr;
		if(m_pRecordset == NULL)
		{
			hr = m_pRecordset.CreateInstance(__uuidof(Recordset));
			if(FAILED(hr))
			{
				m_pRecordset = NULL;
				return FALSE;
			}
			m_pRecordset->CacheSize = 10;
			m_pRecordset->CursorLocation = adUseClient;
		}
		if(m_pRecordset->State != adStateClosed)
			m_pRecordset->Close();
		if(DataType == adNumeric)
			DataType = adVarNumeric;
		hr = m_pRecordset->Fields->Append((_bstr_t)strFieldName,DataType,iSize,Attribute);
		if(FAILED(hr))
			return FALSE;
	}
	catch(_com_error& e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
	}
	return TRUE;
}

BOOL CADORecordset::DeleteField(CString strFieldName)
{
	if(m_pRecordset == NULL)
		return FALSE;
	HRESULT hr = m_pRecordset->Fields->Delete((_bstr_t)strFieldName);
	if(FAILED(hr))
		return FALSE;
	return TRUE;
}

BOOL CADORecordset::CopyFields(CADORecordset* prstSrc)
{
	if(m_pRecordset != NULL && FieldCount() > 0)
	{
		if(IsOpen() && GetRecordCount() > 0)
		{
			MoveFirst();
			for(int i = 0;i < GetRecordCount();i++)
				Delete();
			Update();
			Close();
		}
		for(int i = FieldCount() - 1;i >= 0;i--)
			DeleteField(FieldName(i));
	}
	if(prstSrc != NULL)
	{
		if(m_pRecordset == NULL)
		{
			HRESULT hr = m_pRecordset.CreateInstance(__uuidof(Recordset));
			if(FAILED(hr))
			{
				m_pRecordset = NULL;
				return FALSE;
			}
			m_pRecordset->CacheSize = 10;
		}

		_RecordsetPtr rst = prstSrc->GetRecordset();
		for(long i = 0;i < prstSrc->FieldCount();i++)
			AddField((BSTR)rst->Fields->GetItem(i)->Name,rst->Fields->GetItem(i)->Type,
			rst->Fields->GetItem(i)->DefinedSize,(AdoNS::FieldAttributeEnum)rst->Fields->GetItem(i)->Attributes);
		return TRUE;
	}
//	m_pRecordset = prstSrc->GetRecordset()->Clone(adLockUnspecified);
	return TRUE;
}

void CADORecordset::SetRecordset(_RecordsetPtr prst)
{
	m_pRecordset = prst;
}

BOOL CADORecordset::AppendRecord(CADORecordset* prstSrc)
{
	try
	{
		if(IsOpen() && prstSrc->IsOpen() && 
			FieldCount() == prstSrc->FieldCount())
		{
			for(long i = 0;i < FieldCount();i++)
			{
				if(m_pRecordset->Fields->Item[i]->Type != prstSrc->m_pRecordset->Fields->Item[i]->Type)
					return FALSE;
			}
			prstSrc->MoveFirst();
			while(!prstSrc->IsEOF())
			{
				AddNew();
				for(int i = 0;i < FieldCount();i++)
					SetField(i, (_variant_t&)prstSrc->FieldVARIANT(i));
				prstSrc->MoveNext();
			}
		}
		else
			return FALSE;
	}
	catch(_com_error& e)
	{
		//AfxMessageBox(e.Description());
		OutputDebugString(e.Description());
		return FALSE;
	}
	return Update();
}